package com.kim.common.utilcom.model;

import com.alibaba.fastjson.JSON;
import com.kim.common.utilcom.constants.CodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;
import java.util.Map;

/**
 * 通用返回结果
 */
@Slf4j
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("结果集")
public class Result<T> implements Serializable {

    /**
     * 返回结果
     */
    @ApiModelProperty("返回结果")
    private T data;

    /**
     * 状态码
     */
    @ApiModelProperty("状态码")
    private String respCode;

    /**
     * 消息
     */
    @ApiModelProperty("消息")
    private String respMsg;

    /**
     * 条件
     */
    @ApiModelProperty("条件")
    private transient Map<String, Object> params;

    /**
     * 无结果成功返回常用返回构造器
     */
    public static <T> Result<T> succeed() {
        return succeedWith(null, CodeEnum.SUCCESS.getRetCode(), CodeEnum.SUCCESS.getRetMsg());
    }


    /**
     * 无结果成功返回常用返回构造器
     * @param msg 附带消息
     */
    public static <T> Result<T> succeed(String msg) {
        return succeedWith(null, CodeEnum.SUCCESS.getRetCode(), msg);
    }

    /**
     * 返回结果常用返回构造器
     * @param model 返回结果
     */
    public static <T> Result<T> succeed(T model) {
        return succeedWith(model, CodeEnum.SUCCESS.getRetCode(), CodeEnum.SUCCESS.getRetMsg());
    }

    /**
     * 结果集，成功消息常用返回构造器
     *
     * @param model 返回结果
     * @param msg   附带消息
     */
    public static <T> Result<T> succeed(T model, String msg) {
        return succeedWith(model, CodeEnum.SUCCESS.getRetCode(), msg);
    }

    /**
     * 成功返回构造器
     *
     * @param data 返回结果
     * @param code 状态码
     * @param msg  附带消息
     */
    private static <T> Result<T> succeedWith(T data, String code, String msg) {
        return new Result<T>(data, code, msg, null);
    }

    /**
     * 错误消息（系统控制器用）
     *
     * @param msg 附带消息
     */
    public static <T> Result<T> failed(String msg) {
        return failedWith(null, CodeEnum.ERROR.getRetCode(), msg);
    }

    /**
     * 错误结果、错误消息
     *
     * @param model 返回结果
     * @param msg   附带消息
     */
    public static <T> Result<T> failed(T model, String msg) {
        return failedWith(model, CodeEnum.ERROR.getRetCode(), msg);
    }

    /**
     * 返回错误码、错误信息（RestControllerAdvice使用）
     *
     * @param code 状态码
     * @param msg  附带消息
     */
    public static <T> Result<T> failed(String code, String msg) {
        return new Result<T>(null, code, msg, null);
    }

    /**
     * 错误返回构造器
     *
     * @param data 返回结果
     * @param code 状态码
     * @param msg  附带消息
     */
    private static <T> Result<T> failedWith(T data, String code, String msg) {
        return new Result<T>(data, code, msg, null);
    }

    /**
     * 请求是否成功
     * <p> 结构体增加success字段 </p>
     */
    public boolean isSuccess() {
        return this.respCode.equals(CodeEnum.SUCCESS.getRetCode());
    }

    /**
     * 转化为JSON字符串
     */
    public String toJsonString() {
        return JSON.toJSONString(this);
    }
}

